let fs = require("fs")
let pathApi = require("path")
let iconv = require('iconv-lite');
let jsonFormat = require("json-format")
let baseUrl = "C:/Program Files (x86)/Steam/steamapps/common/Mount & Blade II Bannerlord"


// 获取物件的cn
let SpitemsCN = getCNs(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/Languages/CNs/std_spitems_xml-zho-CN.xml"))

// 获取兵种的cn
let CharacterCN = getCNs(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/Languages/CNs/std_spnpccharacters_xml-zho-CN.xml"))

// 物件解析 护甲
let Arm = getArmor(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/arm_armors.xml"))
let Body = getArmor(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/body_armors.xml"))
let Head = getArmor(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/head_armors.xml"))
let Leg = getArmor(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/leg_armors.xml"))
let Shoulder = getArmor(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/shoulder_armors.xml"))

// 马匹 马凯 解析
let {Horse, HorseArmor} = getHorse(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/items/horses_and_others.xml"))

// 盾牌 武器
let Items = getItems([
    pathApi.resolve(baseUrl, "./Modules/SandBoxCore/ModuleData/items/shields.xml"),
    pathApi.resolve(baseUrl, "./Modules/SandBoxCore/ModuleData/items/tournament_weapons.xml"),
    pathApi.resolve(baseUrl, "./Modules/SandBoxCore/ModuleData/items/weapons.xml"),
])

// character 解析
let characterText = fs.readFileSync(pathApi.resolve(baseUrl,"./Modules/SandBoxCore/ModuleData/spnpccharacters.xml")).toString()
characterText = characterText.match(/<NPCCharacter (?:(?!NPCCharacter>)[\w\W])+<\/NPCCharacter>/g);
let characters = {}
characterText.forEach(characterStr => {
    let characterItem = {}
    normarParse({
        keys:["id","default_group","level","culture"],
        ret:characterItem,
        text:characterStr
    })
    characters[characterItem.id] = characterItem
    if(/name="{=([^}]+)}([^"]+)"/.test(characterStr)){
        characterItem.name = CharacterCN[RegExp.$1] || RegExp.$2;
    }

    // 熟练度解析
    // skill
    characterItem.skill = {};
    (characterStr.match(/<skill[^>]+\/>/g)||[]).forEach(v => {
        let tmp = {}
        normarParse({
            keys:["id","value"],
            ret:tmp,
            text:v
        })
        characterItem.skill[tmp.id] = tmp.value - 0;
    })

    characterItem.equipment = {};
    (characterStr.match(/<equipment[^>]+\/>/g)||[]).forEach(v => {
        let tmp = {}
        normarParse({
            keys:["id","slot"],
            ret:tmp,
            text:v
        })
        tmp.id = tmp.id.replace("Item.", "")
        if(tmp.slot) {
            if(tmp.slot == "Horse"){
                characterItem.equipment[tmp.id] = Horse[tmp.id]
            }
            if(tmp.slot == "HorseHarness"){
                characterItem.equipment[tmp.id] = HorseArmor[tmp.id]
            }
            if(tmp.slot == "Gloves"){
                characterItem.equipment[tmp.id] = Arm[tmp.id]
            }
            if(tmp.slot == "Head"){
                characterItem.equipment[tmp.id] = Head[tmp.id]
            }
            if(tmp.slot == "Body"){
                characterItem.equipment[tmp.id] = Body[tmp.id]
            }
            if(tmp.slot == "Leg"){
                characterItem.equipment[tmp.id] = Leg[tmp.id]
            }
            if(tmp.slot == "Cape"){
                characterItem.equipment[tmp.id] = Shoulder[tmp.id]
            }
            if(/^item/ig.test(tmp.slot)){
                characterItem.equipment[tmp.id] = Items[tmp.id]
            }
            
        }
    })

})


fs.writeFileSync("./armor.json", jsonFormat({...Arm,...Body,...Head,...Leg,...Shoulder}))
fs.writeFileSync("./character.json", jsonFormat(characters))
fs.writeFileSync("./horse.json", jsonFormat({...Horse,...HorseArmor}))
fs.writeFileSync("./items.json", jsonFormat(Items))


function getItems(paths) {
    let ret = {}
    paths.forEach((path, i) => {
        let text = fs.readFileSync(path).toString()
        if(text) {
            let textarr = []
            textarr = text.match(/<Item (?:(?!Item>)[\w\W])+<\/Item>/g) || [];
            textarr = [...textarr, ...(text.match(/<CraftedItem (?:(?!CraftedItem>)[\w\W])+<\/CraftedItem>/g)||[])] ;
            textarr.map(item => {
                let res = {}
                normarParse({
                    keys:["id","Type","weight","hit_points","body_armor","stack_amount", 
                    "thrust_damage", "thrust_damage_type","difficulty","accuracy","thrust_speed","speed_rating"],
                    ret:res,
                    text:item
                })
                
                if(/name="{=([^}]+)}([^"]+)"/.test(item)){
                    res.name = SpitemsCN[RegExp.$1] || RegExp.$2;
                }
                if(res.id) {
                    ret[res.id] = res;
                }
                
                
            })
        }
    })
    return ret;
}

function normarParse (props) {
    let {keys, ret, text} = props
    keys.forEach(key => {
        let reg = new RegExp(`${key}="([^"]+)"`)
        if(reg.test(text)) {
            ret[key] = RegExp.$1;
        }
    })
}

// 解析马匹
function getHorse(path) {
    let ret = {Horse:{}, HorseArmor:{}}
    let text = fs.readFileSync(path).toString()
    if(text) {
        text = text.match(/<Item (?:(?!Item>)[\w\W])+<\/Item>/g);
        text.map(item => {
            let res = {}
            if(/id="([^"]+)"/.test(item)){
                res.id = RegExp.$1
            }
            if(/name="{=([^}]+)}([^"]+)"/.test(item)){
                res.name = SpitemsCN[RegExp.$1] || RegExp.$2;
            }
            if(/weight="([^"]+)"/.test(item)){
                res.weight = RegExp.$1 - 0;
            }
            if(/Type="([^"]+)"/.test(item)){
                res.Type = RegExp.$1;
                if(res.Type == "Horse") {
                    ret.Horse[res.id] = res
                    if(/item_category="([^"]+)"/.test(item)){
                        res.item_category = RegExp.$1;
                    }
                    if(/difficulty="([^"]+)"/.test(item)){
                        res.difficulty = RegExp.$1-0;
                    }
                    if(/extra_health="([^"]+)"/.test(item)){
                        res.hp = RegExp.$1 - 0 + 200;
                    }
                    if(/speed="([^"]+)"/.test(item)){
                        res.speed = RegExp.$1 - 0;
                    }
                    if(/maneuver="([^"]+)"/.test(item)){
                        res.maneuver = RegExp.$1 - 0;
                    }
                    if(/charge_damage="([^"]+)"/.test(item)){
                        res.charge_damage = RegExp.$1 - 0;
                    }
                    if(/body_length="([^"]+)"/.test(item)){
                        res.body_length = RegExp.$1 - 0;
                    }
                } else if (res.Type == "HorseHarness") {
                    ret.HorseArmor[res.id] = res
                    if(/body_armor="([^"]+)"/.test(item)){
                        res.armor = RegExp.$1 - 0;
                    }
                }
            }
        })
    }
    return ret;
}

// 获取对应路径 cns
function getCNs (path) {
    let CNS = {}
    let buffer = fs.readFileSync(path);
    let text = iconv.decode(buffer,"utf-16");
    if(text) {
        text = text.match(/<string id=".+" text="[^"]+"\/>/g);
        text.forEach( v => {
            if(/<string id="(.+)" text="([^"]+)"\/>/.test(v)){
                CNS[RegExp.$1] = RegExp.$2
            }
        })
    }
    return CNS
}

// 获取护甲数据
function getArmor(path) {
    let text = fs.readFileSync(path).toString()
    if(text) {
        text = text.match(/<Item (?:(?!Item>)[\w\W])+<\/Item>/g);
        let res = {}
        text.map(item => {
            let ret = {}
            if(/id="([^"]+)"/.test(item)){
                ret.id = RegExp.$1;
                res[ret.id] = ret
            }
            if(/name="{=([^}]+)}([^"]+)"/.test(item)){
                ret.name = SpitemsCN[RegExp.$1] || RegExp.$2;
            }
            if(/weight="([^"]+)"/.test(item)){
                ret.weight = RegExp.$1 - 0;
            }
            if(/Civilian="([^"]+)"/.test(item)){
                ret.Civilian = !!RegExp.$1;
            }
            if(/ ([a-zA-Z]+_armor)="([^"]+)"/.test(item)){
                ret.armor = {}
                let armor = 0;
                item.match(/([a-zA-Z]+_armor)="([^"]+)"/g).forEach(v => {
                    let tmp = v.split("=")
                    ret.armor[tmp[0]] = tmp[1].replace(/"/g, "")-0;
                    if(ret.armor[tmp[0]] && ret.armor[tmp[0]] != NaN) {
                        armor += ret.armor[tmp[0]] 
                    }
                })
                ret.armorAdd = armor
                if(ret.weight) {
                    ret.point = armor / (ret.weight)
                }
            }
        })
        return res
    }
}